﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleAppNetworkTestAndToEmail
{
    /// <summary>
    /// 处理要检测的主机列表。
    /// </summary>
    /// 创建时间：2022-12-16 14:56:31。作者：王浩力
    internal class TestingBusiness
    {
        /// <summary>
        /// 累计错误记录
        /// </summary>
        internal class LogErrorInfo
        {
            /// <summary>
            /// 累计的错误次数
            /// </summary>
            public int ErrorCount { get; set; }

            /// <summary>
            /// 上一次错误时间
            /// </summary>
            public DateTime LastTime { get; set; }
        }

        /// <summary>
        /// 记录错误次数
        /// </summary>
        static Dictionary<string, LogErrorInfo> logErrorCheck = new Dictionary<string, LogErrorInfo>();

        /// <summary>
        /// 上一次发送时间
        /// </summary>
        static Dictionary<string, DateTime> sendHistoryList = new Dictionary<string, DateTime>();

        internal static void PingHostList()
        {
            int error_threshold = 0;
            if (!int.TryParse(MyConfigReader.GetConfigValue("disconnected_seconds"), out error_threshold))
            {
                error_threshold = 3;
            }
            if (error_threshold <= 1)
            {
                error_threshold = 1;
            }
            //检隔多少秒检测地址一次
            int testing_seconds = 0;
            if (!int.TryParse(MyConfigReader.GetConfigValue("testing_seconds"), out testing_seconds))
            {
                testing_seconds = 30;
            }

            //检测列表
            var list = MyConfigReader.GetConfigList("testing_address_list");
            foreach (var item in list)
            {
                try
                {
                    var result = PingURLHelpter.TcpIpPing(item);
                    if (result.HttpStatusCode == 500)
                    {
                        LogErrorInfo log = new LogErrorInfo();
                        if (!logErrorCheck.TryGetValue(item, out log))
                        {
                            log = new LogErrorInfo()
                            {
                                LastTime = DateTime.Now,
                                ErrorCount = 0
                            };
                        }
                        //判断上一次的错误时间，在检隔时间内才记录错误
                        double totalSpan = (DateTime.Now - log.LastTime).TotalSeconds;
                        LogHelpter.AddLog($"{item}离上一次的错误时间" + totalSpan);
                        if (totalSpan <= testing_seconds * 3)
                        {
                            if (log.ErrorCount >= error_threshold - 1)
                            {
                                logErrorCheck.Remove(item);

                                LogHelpter.AddLog($"{item}触发阈值，发送异常邮件");

                                //达到阈值错误发送邮件通知
                                var emailList = MyConfigReader.GetConfigList("notify_email_list");
                                var emailSeverList = emailList.ToArray();
                                foreach (var emailInfo in emailSeverList)
                                {
                                    DateTime lastTime ;
                                    //两小时内发了的，不在发送
                                    sendHistoryList.TryGetValue(item,out lastTime);
                                    if ((DateTime.Now- lastTime).TotalSeconds<7200)
                                    {
                                        LogHelpter.AddLog($"{item},两小时内发了的，不在发送");
                                        continue;
                                    }

                                    //收件人
                                    string email = emailInfo.Split("--%$password--", StringSplitOptions.RemoveEmptyEntries)[0];
                                    //收件人，客户端授权码
                                    string authCode = emailInfo.Split("--%$password--", StringSplitOptions.RemoveEmptyEntries)[1];

                                    string mailFrom = email;
                                    string mailTo = email;
                                    string mailAccount = email;
                                    string password = authCode;//客户端授权码
                                    string title = $"主机{item}无法访问";
                                    string content = $"主机{item}无法访问，<br/>检测时间：{DateTime.Now.ToString("yyyy - MM - dd HH: mm: ss")}";

                                    if (mailTo.Contains("qq.com"))
                                    {
                                        SendEmailTool.TestSmtpClient(mailFrom, mailTo, title, content, mailAccount, password, ServerType.SERVER_qq_COM);
                                    }
                                    else if (mailTo.Contains("163.com"))
                                    {
                                        SendEmailTool.TestSmtpClient(mailFrom, mailTo, title, content, mailAccount, password, ServerType.SERVER_163_COM);
                                    }
                                    else
                                    {
                                        Console.WriteLine("没有找到邮件服务器");
                                    }

                                    //记录这次发送时间
                                    sendHistoryList.Remove(item);
                                    sendHistoryList.Add(item, DateTime.Now);
                                }
                            }
                            else
                            {
                                LogHelpter.AddLog($"{item},记录错误'");
                                //记录错误
                                int total = log.ErrorCount + 1;
                                logErrorCheck.Remove(item);
                                logErrorCheck.TryAdd(item, new LogErrorInfo() { LastTime = DateTime.Now, ErrorCount = total });
                            }
                        }
                        int total2 = log.ErrorCount + 1;
                        logErrorCheck.Remove(item);
                        logErrorCheck.TryAdd(item, new LogErrorInfo() { LastTime = DateTime.Now, ErrorCount = total2 });
                    }

                }
                catch (Exception ex)
                {
                    LogHelpter.AddLog("检测出错" + ex.Message, null, "error");
                }
                //for 结束
            }

        }


    }
}
